package com.salmon.common.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

/**
 * 自定义响应结构, 转换类
 */
public class JacksonUtils {

    // 定义jackson json 对象
    private static final ObjectMapper MAPPER = new ObjectMapper();
    // 定义jackson xml 对象
    private static final XmlMapper xmlMapper = new XmlMapper();

    static {
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MAPPER.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        MAPPER.setTimeZone(TimeZone.getTimeZone("CTT")); // CTT - Asia/Shanghai
        MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        xmlMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
        xmlMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        xmlMapper.setTimeZone(TimeZone.getTimeZone("CTT")); // CTT - Asia/Shanghai
    }

    //--------------------------------------XML工具---------------------------------------------

    /**
     * 输出全部属性 如果xml中存在，对象中没有，则自动忽略该属性 失败返回null
     */
    public static <T> T xmlToBean(String xmlContent, Class<T> clazz) {
        try {
            return xmlMapper.readValue(xmlContent, clazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 输出全部属性 如果xml中存在，对象中没有，则自动忽略该属性 失败返回null
     */
    public static <T> T xmlToBean(InputStream inputStream, Class<T> clazz) {
        try {
            return xmlMapper.readValue(inputStream, clazz);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 输出全部属性 失败返回 ""
     */
    public static String toXml(Object object) {
        try {
            return xmlMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 输出全部属性 失败返回 ""
     */
    public static String toPrettyXml(Object object) {
        try {
            return xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 将xml数据转换成pojo对象list
     */
    public static <T> List<T> xmlToList(String xmlContent, Class<T> beanType) {
        JavaType javaType = xmlMapper.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            return xmlMapper.readValue(xmlContent, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static <K, V> Map<K, V> xmlToMap(Class<K> keyClazz, Class<V> valueClazz, String xml) {
        try {
            return xmlMapper.readValue(xml, xmlMapper.getTypeFactory().constructMapType(HashMap.class, keyClazz, valueClazz));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //---------------------------------------------json工具------------------------------------------------

    /**
     * 将对象转换成json字符串。
     * <p>Title: pojoToJson</p>
     * <p>Description: </p>
     * @param data
     * @return
     */
    public static String toJson(Object data) {
    	try {
			return MAPPER.writeValueAsString(data);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @param beanType 对象中的object类型
     * @return
     */
    public static <T> T jsonToBean(String jsonData, Class<T> beanType) {
        try {
            return MAPPER.readValue(jsonData, beanType);
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json数据转换成pojo对象list
     * <p>Title: jsonToList</p>
     * <p>Description: </p>
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
    	JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
    	try {
    		return MAPPER.readValue(jsonData, javaType);
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return null;
    }

    public static <K, V> Map<K, V> jsonToMap(Class<K> keyClazz, Class<V> valueClazz, String json) {
        try {
            return MAPPER.readValue(json, MAPPER.getTypeFactory().constructMapType(HashMap.class, keyClazz, valueClazz));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
}
